/*
* Copyright 2023 NXP
* NXP Proprietary. This software is owned or controlled by NXP and may only be used strictly in
* accordance with the applicable license terms. By expressly accepting such terms or by downloading, installing,
* activating and/or otherwise using the software, you are agreeing that you have read, and that you agree to
* comply with and are bound by, such license terms.  If you do not agree to be bound by the applicable license
* terms, then you may not retain, install, activate or otherwise use the software.
*/


/*********************
 *      INCLUDES
 *********************/
#include <stdio.h>
#include "lvgl.h"
#include "custom.h"

#include "esp_log.h"

#include "gui_guider.h"
#include "wifi_sta.h"

#define TAG "custom"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/

/**
 * Create a demo application
 */

void custom_init(lv_ui *ui)
{
    /* Add your codes here */
}

void custom_set_main_time(lv_ui *ui, int hour, int min, int sec)
{
    char buf[16];
    snprintf(buf, sizeof(buf), "%02d:%02d\n%02d", hour, min, sec);
    if(ui && ui->main && ui->main_label_time)
    {
        lv_label_set_text(ui->main_label_time, buf);
    }
    else
    {
        ESP_LOGI(TAG, "time:%s, ui:%p, lb:%p, guider_ui:%p", buf, ui, ui->main_label_time, &guider_ui);
    }
}
#include "time.h"
void custom_update_time(lv_ui *ui)
{
    time_t t = time(NULL);
    struct tm *tm;
    t += 8*3600;
    tm = localtime(&t);
    if(ui == NULL)
    {
        ui = &guider_ui;
    }
    custom_set_main_time(ui, tm->tm_hour, tm->tm_min, tm->tm_sec);
}

void custom_clear_wifi_list(lv_ui *ui)
{
    lv_obj_t *parent = ui->wifi_list_wifis;
    lv_obj_t *child;
    while(lv_obj_get_child_cnt(parent) > 1)
    {
        child = lv_obj_get_child(parent, 1);
        lv_obj_del(child);
    }
}

static void wifi_list_wifis_item_x_event_handler (lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    switch (code) {
    case LV_EVENT_CLICKED:
    {
        const char *cur_wifi = lv_list_get_btn_text(guider_ui.wifi_list_wifis, lv_event_get_target(e));
        char buf[64];
        int len = strlen(cur_wifi);
        len = len > sizeof(buf)-1 ? sizeof(buf)-1 : len;
        memcpy(buf, cur_wifi, len);
        buf[len] = '\0';
        ESP_LOGI(TAG, "wifi:%s=>%s", cur_wifi, buf);
        ui_load_scr_animation(&guider_ui, &guider_ui.get_passwd, guider_ui.get_passwd_del, &guider_ui.wifi_del, setup_scr_get_passwd, LV_SCR_LOAD_ANIM_MOVE_LEFT, 200, 200, false, true);
        lv_label_set_text(guider_ui.get_passwd_label_wifi, buf);
        break;
    }
    case LV_EVENT_DRAW_MAIN_BEGIN:
    {
        ;
        break;
    }
    default:
        break;
    }
}
void custom_add_wifi_list(lv_ui *ui, const char *str)
{
    lv_obj_t *parent = ui->wifi_list_wifis;
    lv_obj_t *item = lv_list_add_btn(parent, LV_SYMBOL_WIFI, str);
    lv_obj_add_event_cb(item, wifi_list_wifis_item_x_event_handler, LV_EVENT_ALL, ui);
}

void custom_set_wifi_list(lv_ui *ui, wifi_ap_record_t *records, uint16_t num)
{
    char item_temp[64];
    custom_clear_wifi_list(ui);
    for(uint16_t i = 0; i < num; i++)
    {
        wifi_ap_record_t *record = &records[i];
        int authmode = record->authmode;
        int strlen = snprintf(item_temp, sizeof(item_temp), "%s,%d,%d,%s", 
            record->ssid, record->primary, record->rssi, wifi_sta_auth_method_name(authmode));
        item_temp[strlen] = '\0';
        custom_add_wifi_list(ui, item_temp);
    }
}

int custom_check_device_list(lv_ui *ui, const char *device)
{
    int num = lv_obj_get_child_cnt(ui->main_list_devices);
    int idx;
    for(idx=0; idx<num; idx++)
    {
        const char *text = lv_list_get_btn_text(ui->main_list_devices, lv_obj_get_child(ui->main_list_devices, idx));
        if(strcmp(text, device) == 0)
        {
            break;
        }
    }
    if(idx < num)
    {
        ESP_LOGI(TAG, "device is exist, %d", idx);
        return true;
    }
    return false;
}
static void main_list_devices_item_event_handler (lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_ui *ui = (lv_ui *)lv_event_get_user_data(e);
    switch (code) {
    case LV_EVENT_CLICKED:
    {
        lv_obj_t *btn = lv_event_get_target(e);
        const char *text = lv_list_get_btn_text(ui->main_list_devices, btn);
        if(btn && text)
        {
            custom_select_device_list(ui, text);
        }
        break;
    }
    default:
        break;
    }
}
int custom_add_device_list(lv_ui *ui, const char *device)
{
    lv_obj_t *btn;
    int cnt = lv_obj_get_child_cnt(ui->main_list_devices);
    if(cnt == 0)
    {
        btn = lv_list_add_btn(ui->main_list_devices, LV_SYMBOL_OK, device);
    }
    else
    {
        btn = lv_list_add_btn(ui->main_list_devices, LV_SYMBOL_BARS, device);
    }
    if(btn == NULL)
    {
        ESP_LOGW(TAG, "add device %s list failed", device);
        return false;
    }
    if(cnt == 0)
    {
        ui->main_list_devices_selected_item = btn;
    }
    lv_obj_add_style(btn, ui->main_list_devices_item_style, LV_PART_MAIN|LV_STATE_DEFAULT);
    lv_obj_add_event_cb(btn, main_list_devices_item_event_handler, LV_EVENT_ALL, ui);
    return true;
}
int custom_select_device_list(lv_ui *ui, const char *device)
{
    int num = lv_obj_get_child_cnt(ui->main_list_devices);
    int idx;
    int selected = -1;
    lv_obj_t *btn;
    lv_obj_t *img;
    for(idx=0; idx<num; idx++)
    {
        btn = lv_obj_get_child(ui->main_list_devices, idx);
        const char *text = lv_list_get_btn_text(ui->main_list_devices, btn);
        img = lv_obj_get_child(btn, 0);
        lv_img_set_src(img, LV_SYMBOL_BARS);
        if(strcmp(text, device) == 0)
        {
            selected = idx;
        }
    }
    if(selected == -1)
    {
        return false;
    }
    for(idx=0; idx<num; idx++)
    {
        btn = lv_obj_get_child(ui->main_list_devices, idx);
        const char *text = lv_list_get_btn_text(ui->main_list_devices, btn);
        img = lv_obj_get_child(btn, 0);
        if(idx == selected)
        {
            lv_img_set_src(img, LV_SYMBOL_OK);
            ui->main_list_devices_selected_item = btn;
        }
        else
        {
            lv_img_set_src(img, LV_SYMBOL_BARS);
        }
    }
    return true;
}
int custom_get_select_device_list_idx(lv_ui *ui)
{
    int selected = -1;
    int num = lv_obj_get_child_cnt(ui->main_list_devices);
    int idx;
    lv_obj_t *btn;
    lv_obj_t *img;
    for(idx=0; idx<num; idx++)
    {
        btn = lv_obj_get_child(ui->main_list_devices, idx);
        img = lv_obj_get_child(btn, 0);
        const char *img_src = lv_img_get_src(img);
        if((const void *)img_src == (const void *)LV_SYMBOL_OK)
        {
            selected = idx;
            break;
        }
        else if(((*(uint32_t*)img_src)&0xFFFFFF) == ((*(uint32_t*)LV_SYMBOL_OK)&0xFFFFFF))
        {
            selected = idx;
            break;
        }
        else
        {
            ESP_LOGW(TAG, "unknown symbol:%p, OK:%p, BARS:%p", img_src, LV_SYMBOL_OK, LV_SYMBOL_BARS);
            ESP_LOGW(TAG, "unknown symbol:%02x%02x%02x/%06x, OK:%02x%02x%02x/%06x, BARS:%02x%02x%02x/%06x"
                , img_src[0], img_src[1], img_src[2],((*(uint32_t*)img_src)&0xFFFFFF)
                , (LV_SYMBOL_OK)[0], (LV_SYMBOL_OK)[1], (LV_SYMBOL_OK)[2], ((*(uint32_t*)LV_SYMBOL_OK)&0xFFFFFF)
                , (LV_SYMBOL_BARS)[0], (LV_SYMBOL_BARS)[1], (LV_SYMBOL_BARS)[2], ((*(uint32_t*)LV_SYMBOL_BARS)&0xFFFFFF));
        }
    }
    return selected;
}
const char *custom_get_select_device_list(lv_ui *ui)
{
    int selected = custom_get_select_device_list_idx(ui);
    if(selected == -1)
    {
        return NULL;
    }
    int num = lv_obj_get_child_cnt(ui->main_list_devices);
    int idx;
    lv_obj_t *btn = lv_obj_get_child(ui->main_list_devices, selected);
    return lv_label_get_text(lv_obj_get_child(btn, 1));
}

void custom_set_main_led(lv_ui *ui, int state)
{
    if(state)
    {
        lv_led_set_brightness(ui->main_led, 255);
    }
    else
    {
        lv_led_set_brightness(ui->main_led, 180);
    }
}

void custom_update_device_data(lv_ui *ui, int led, const char *humi, const char *temp)
{
    if(led)
    {
        lv_obj_add_state(ui->main_sw_led, LV_STATE_CHECKED);
    }
    else
    {
        lv_obj_clear_state(ui->main_sw_led, LV_STATE_CHECKED);
    }
    custom_set_main_led(ui, led);
    if(humi && temp && humi[0] && humi[1])
    {
        lv_label_set_text(ui->main_label_temp, temp);
        lv_label_set_text(ui->main_label_humi, humi);
        lv_tabview_set_act(ui->main_tabview_dev, 0, LV_ANIM_OFF);
        ESP_LOGI(TAG, "humi:%s, temp:%s", humi, temp);
    }
    else
    {
        lv_tabview_set_act(ui->main_tabview_dev, 1, LV_ANIM_OFF);
    }
}

extern void appm_set_led_status(const char *device, int led);
void custom_set_led_status(const char *device, int led)
{
    appm_set_led_status(device, led);
}